package com.lk.mall.config.handler;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lk.mall.common.MallException;
import com.lk.mall.config.annotation.TokenToMallUser;
import com.lk.mall.model.entity.User;
import com.lk.mall.model.entity.UserToken;
import com.lk.mall.mapper.UserMapper;
import com.lk.mall.mapper.UserTokenMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 1、HandlerMethodArgumentResolver 参数解析器 有2个方法
    - boolean supportsParameter(MethodParameter parameter);
    作用是判断Controller层中的参数，是否满足条件，满足条件则执行resolveArgument方法，不满足则跳过。

    - Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
    NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) ;
    只有在 supportsParameter 方法返回 true 的情况下才会被调用。
    用于处理一些业务，将返回值赋值给Controller层中的这个参数。

 https://blog.csdn.net/qq_36408229/article/details/104436508

 2、MethodParameter  org.springframework.core


 */
@Component
public class TokenToMallUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Resource
    private UserMapper mallUserMapper;
    @Resource
    private UserTokenMapper newBeeMallUserTokenMapper;

    public TokenToMallUserMethodArgumentResolver() {
    }

    /**
     * @description
     * @author Lemonade
     * @param parameter
     * @updateTime 2022/9/8 15:14
     * @return boolean
     */
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(TokenToMallUser.class);
    }

    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        // instanceof 关键字

        //if (parameter.getParameterAnnotation(TokenToMallUser.class) instanceof TokenToMallUser) {
        if (parameter.getParameterAnnotation(TokenToMallUser.class) != null) {

            User mallUser = null;
            String token = webRequest.getHeader("token");

            if (null != token && !"".equals(token) && token.length() == 32) {
                UserToken mallUserToken = newBeeMallUserTokenMapper.selectByToken(token);
                // token 过期
                if (mallUserToken == null || mallUserToken.getExpireTime().getTime() <= System.currentTimeMillis()) {
                    MallException.fail("");
                }

                LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(User::getUserId, mallUserToken.getUserId());
                mallUser = mallUserMapper.selectOne(queryWrapper);

                if (mallUser == null) {
                    MallException.fail("");
                }
                if (mallUser.getLockedFlag() == 1) {
                    MallException.fail("");
                }
                return mallUser;
            } else {
                MallException.fail("");
            }
        }
        return null;
    }

    //public static byte[] getRequestPostBytes(HttpServletRequest request)
    //        throws IOException {
    //    int contentLength = request.getContentLength();
    //    if (contentLength < 0) {
    //        return null;
    //    }
    //    byte buffer[] = new byte[contentLength];
    //    for (int i = 0; i < contentLength; ) {
    //        int readlen = request.getInputStream().read(buffer, i,
    //                contentLength - i);
    //        if (readlen == -1) {
    //            break;
    //        }
    //        i += readlen;
    //    }
    //    return buffer;
    //}

}
